package com.turing.post.thirdinterface.impl;

import java.math.BigInteger;
import java.util.Date;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.turing.post.account.util.OnlineTransferDetail;
import com.turing.post.account.util.OnlineTransferDetailDao;
import com.turing.post.account.util.SubAccountBusiness;
import com.turing.post.cardmanagement.util.ActivateCard;
import com.turing.post.cardmanagement.util.ActivateCardDao;
import com.turing.post.organization.util.BankManage;
import com.turing.post.organization.util.BankTranBusiness;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.salesmanage.util.PersonalCustom;
import com.turing.post.salesmanage.util.PersonalCustomDao;
import com.turing.post.salesmanage.util.SaleOrder;
import com.turing.post.salesmanage.util.SaleOrderCardDetail;
import com.turing.post.salesmanage.util.SaleOrderCardDetailDao;
import com.turing.post.salesmanage.util.SaleOrderDao;
import com.turing.post.thirdinterface.util.ThirdInterfaceApplicationException;
import com.turing.post.thirdinterface.util.ThirdInterfaceRespCode;
import com.turing.post.transaction.util.ChkAccFileBusiness;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * JNDI thirdinterface.impl.BankTranBusinessImpl
 * 
 * @author zxppanda
 * 
 */
@Stateless(mappedName = "thirdinterface.impl.BankTranBusinessImpl")
@Remote
@Local
public class PSBCBankTranBusinessImpl implements BankTranBusiness {

	@EJB(mappedName = "account.impl.OnlineTransferDetailDaoImpl")
	private OnlineTransferDetailDao otdDao;

	// @EJB(mappedName = "common.impl.SysOpUserDaoImpl")
	// private SysOpUserDao sysOpUserDao;
	//	
	@EJB(mappedName = "cardmanagement.impl.ActivateCardDaoImpl")
	private ActivateCardDao acDao;
	//	
	// @EJB(mappedName = "cardmanagement.impl.CardClassicDaoImpl")
	// private CardClassicDao cardClassicDaoImpl;

	@EJB(mappedName = "account.impl.SubAccountBusinessImpl")
	private SubAccountBusiness subAccount;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "salesmanage.impl.PersonalCustomDaoImpl")
	private PersonalCustomDao personalCustomDao;

	// @EJB(mappedName = "common.impl.IdTypeDaoImpl")
	// private IdTypeDao idTypeDao;

	@EJB(mappedName = "salesmanage.impl.SaleOrderCardDetailDaoImpl")
	private SaleOrderCardDetailDao saleOrderCardDetailDao;

	@EJB(mappedName = "salesmanage.impl.SaleOrderDaoImpl")
	private SaleOrderDao saleOrderDao;

	@EJB(mappedName = "transaction.impl.ChkAccFileBusinessImpl")
	private ChkAccFileBusiness chkAccFileBusinessImpl;

	@Override
	public void BankCardIssuePre(BankManage bm, String cardNo, Object privobj)
			throws PCPSApplicationException {

	}

	@Override
	public void BankCardIssuePost(BankManage bm, String cardNo, Object privobj)
			throws PCPSApplicationException {
		// 验证参数
		if (bm == null || PCPSUtil.isEmpty(bm.getServiceAddr())
				|| PCPSUtil.isEmpty(cardNo)) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_ARGS_NULL, "参数为空!");
		}
		// 得到卡的主帐号
		ActivateCard ac = acDao.getActivateCardByCardNo(cardNo);
		if (ac == null || ac.getOwnerId() == null
				|| ac.getMasterAccNo() == null) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_INFO_ERROR, "此卡信息有误!");
		}
		// 得到持卡人信息
		PersonalCustom pc = personalCustomDao.getPersonalCustomByPersonalId(ac
				.getOwnerId());
		if (pc == null) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_ARGS_NULL, "持卡人信息为空!");
		}
		// 得到销售单售卡明细信息
		SaleOrderCardDetail sc = saleOrderCardDetailDao
				.getSaleOrderCardDetailByBatchNo(ac.getBatchNo(), ac
						.getCardSeqNo(), ac.getCardSeqNo());
		if (sc == null) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_ARGS_NULL, "此刻销售记录为空!");
		}
		// 得到销售单信息
		SaleOrder so = saleOrderDao.getSaleOrderBySaleOrderId(sc
				.getSaleOrderId());

		// 封装请求对象
		PSBCBankResponse psbcResponse = new PSBCBankResponse();
		psbcResponse.tradeId = PSBCBankXmlHelper.XML_OPENCARD;
		psbcResponse.teller = so.getOperId().toString();
		psbcResponse.enterprise = bm.getDelegateNo();
		psbcResponse.custId = ac.getMasterAccNo().toString();
		psbcResponse.dptId = ac.getCardClassicId().toString();
		psbcResponse.custName = pc.getName();
		psbcResponse.passId = pc.getIdNo();
		psbcResponse.payerType = PSBCBankXmlHelper.XML_IDTYPE;
		psbcResponse.accType = PSBCBankXmlHelper.XML_ACC;
		psbcResponse.acc = ac.getCardNo();
		psbcResponse.tradeSeq = so.getSaleOrderSeqNo();

		// 联机交易
		PSBCSocketOnline psbcSocket = new PSBCSocketOnline();
		PSBCBankRequest psbcRequest = null;
		try {
			psbcRequest = psbcSocket.PSBCControlConnectTime(bm, psbcResponse);
		} catch (Exception e) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_SOCKET, "与邮储银行联机通讯失败!");
		}
		// 检查联机信息是否正确
		if (!PSBCBankXmlHelper.XML_SUCCESS.equals(psbcRequest.retCode)) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_INFO_ERROR, "银行卡签约失败!");
		}
	}

	@Override
	public void BankCardSpecial(BankManage bm, String cardNo, String tranType,
			Object privobj) throws PCPSApplicationException {
		// TODO Auto-generated method stub

	}

	/**
	 * 卡联机转账(转入、转出)
	 */
	@Override
	public void BankCardOnlineTransfer(BankManage bm, String localSeqNo)
			throws PCPSApplicationException {
		// 1.获取联机转入/转出流水
		OnlineTransferDetail otd = otdDao
				.getOnlineTransferDetailByLocalSeqNo(localSeqNo);
		if (otd == null) {
			errException("联机转账明细未获取到!");
		}
		// 2.封装请求对象
		PSBCBankResponse psbcResponse = new PSBCBankResponse();
		// 取激活卡信息
		ActivateCard ac = acDao.getActivateCardByCardNo(otd.getCardNo());
		// 取卡系统全局数据字典
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(otd.getIssueCompanyNo());

		psbcResponse.tradeId = PSBCBankXmlHelper.XML_DEPOSIT;
		psbcResponse.teller = otd.getOperId().toString();
		psbcResponse.enterprise = bm.getDelegateNo();
		psbcResponse.custId = otd.getMasterAccNo().toString();
		psbcResponse.dptId = ac.getCardClassicId().toString();
		psbcResponse.moneyTrade = otd.getAmount().toString();
		psbcResponse.tradeSeq = localSeqNo;

		// 3.联机交易
		PSBCSocketOnline psbcSocket = new PSBCSocketOnline();
		PSBCBankRequest psbcRequest = null;
		try {
			psbcRequest = psbcSocket.PSBCControlConnectTime(bm, psbcResponse);
		} catch (Exception e) {
			otdDao.updateOnlineTransferDetailStatus(localSeqNo,
					OnlineTransferDetail.OnlineTransfer_Status_fail, null);
			errException("与邮储银行联机通讯失败!");
		}

		// 4.更新联机转账明细AccSeqNo
		if (PSBCBankXmlHelper.XML_SUCCESS.equals(psbcRequest.retCode)) {
			// 5.账户子系统记账,返回记账流水
			String accSeqNo = subAccount.insertSubAccountInfo(otd.getCardNo(),
					otd.getAmount(), otd.getRemark(), issueCompany, otd
							.getTranTime(), localSeqNo);
			otd.setStatus(OnlineTransferDetail.OnlineTransfer_Status_success);
			otd.setBankRespCode(psbcRequest.retCode);
			otd.setBankAckSeqNo(psbcRequest.bankSeq);
			otd.setAccSeqNo(accSeqNo);
			otdDao.update(otd);
		} else {
			otdDao.updateOnlineTransferDetailStatus(localSeqNo,
					OnlineTransferDetail.OnlineTransfer_Status_fail,
					psbcRequest.retCode);
			errException(psbcRequest.msg);
		}
	}

	@Override
	public void BankCardCheckAccount(BankManage bm, Date tranDate,
			Object privobj) throws PCPSApplicationException {

		PSBCBankResponse psbcResponse = new PSBCBankResponse();
		psbcResponse.tradeId = PSBCBankXmlHelper.XML_DEPOSIT;
		psbcResponse.teller = privobj.toString();
		psbcResponse.enterprise = bm.getDelegateNo();
		psbcResponse.tradeDate = PCPSUtil.getPackedYMDString2(tranDate);
		psbcResponse.fileName = "";
		PSBCSocketOnline psbcSocket = new PSBCSocketOnline();
		PSBCBankRequest psbcRequest = null;
		try {
			psbcRequest = psbcSocket.PSBCControlConnectTime(bm, psbcResponse);
		} catch (Exception e) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_SOCKET, "与邮储银行联机通讯失败!");
		}
		// 检查联机信息是否正确
		if (!PSBCBankXmlHelper.XML_SUCCESS.equals(psbcRequest.retCode)) {
			throw new ThirdInterfaceApplicationException(
					ThirdInterfaceApplicationException.ERRMSG_NULLPOINTER,
					ThirdInterfaceRespCode.RC_INFO_ERROR, "与邮储银行联机对账失败!");
		} else {
			// 核对总帐
			String[] flag = bankCheckAccount(bm.getChkAccFtpAddr(),
					psbcResponse.fileName.toString(), psbcResponse.tradeDate);
			if (!Boolean.parseBoolean(flag[0])) { // 核对充值明细
				boolean tem = bankCheckDetailAccount(bm.getChkAccFtpAddr(),
						psbcResponse.fileName.toString(),
						psbcResponse.tradeDate, 0);
				if (!tem)
					System.out.println("0000000000");
			}
		}

	}

	// 核对总帐	
	private String[] bankCheckAccount(String ftpAddr, String fileName,
			String Trandate) throws PCPSApplicationException {
		String[] bool = new String[2]; 
		byte[] byt = chkAccFileBusinessImpl.getRemoteFile(ftpAddr, fileName);
		String bankInfo = new String(byt);
		String[] temp = bankInfo.split("\n");
		boolean rechargeFlag = true;
		boolean ransomFlag = true;
		for (int i = 0; i < temp.length; i++) {
			String[] value = temp[i].split("\\|");
			String type = value[0]; // 类型 00-代扣，01-代发，02-换卡
			String count = value[1]; // 总笔数
			String amount = value[2]; // 总金额
			int t = Integer.valueOf(type).intValue();
			Object[] obj = null;
			switch (t) {
			case 0: // 充值
				obj = otdDao.checkAccuntByTrandateAndTranType(Trandate, "0");
				if (!count.equals(obj[0]) || !amount.equals(obj[1])) {
					// 记录日志 充值总笔数，总金额核对错误

					rechargeFlag = false;
				} else {// 修改所有对账状态为一致
					otdDao.updateCheckAccuntSuccessDetail(Trandate, "0");
				}
				break;
			case 1: // 赎回
				obj = otdDao.checkAccuntByTrandateAndTranType(Trandate, "1");
				if (!count.equals(obj[0]) || !amount.equals(obj[1])) {
					// 记录日志 赎回总笔数，总金额核对错误

					ransomFlag = false;
				} else {// 修改所有对账状态为一致
					otdDao.updateCheckAccuntSuccessDetail(Trandate, "1");
				}
				break;
			case 2: // 换卡
				System.out.println("2");
				break;
			}
		}
		bool[0] = String.valueOf(rechargeFlag);
		bool[1] = String.valueOf(ransomFlag);
		return bool;
	}

	// 核对明细
	private boolean bankCheckDetailAccount(String ftpAddr, String fileName,
			String Trandate, int checkType) throws PCPSApplicationException {
		byte[] byt = chkAccFileBusinessImpl.getRemoteFile(ftpAddr, fileName);
		String bankInfo = new String(byt);
		String[] temp = bankInfo.split("\n");
		boolean flag = true;
		for (int i = 0; i < temp.length; i++) {
			String[] value = temp[i].split("\\|");
			String type = value[0]; // 类型 00-代扣，01-代发
			String xCardNo = value[1]; // 西邮寄主账号
			String senCardNo = value[2]; // 西邮寄委托单位号
			String bCardNo = value[3]; // 卡/帐户号码
			String localSeqNo = value[4]; // 西邮寄交易流水号
			String trandate = value[5]; // 交易发起时间
			String amount = value[6]; // 支付金额
			String accSeqNo = value[7]; // 银行交易流水号
			String status = value[8]; // 交易状态
			int t = Integer.valueOf(type).intValue();
			OnlineTransferDetail otd = null;
			switch (t) {
			case 0: // 充值
				otd = otdDao.getOnlineTransferDetailByLocalSeqNo(localSeqNo);
				if (BigInteger.valueOf(Long.parseLong(amount)) != otd
						.getAmount()) {
					// 记录日志 该条交易明细核对错误

					// 修改对账状态为不一致
					otd.setCheckStatus("2");
					flag = false;
				} else { // 修改对账状态为一致
					otd.setCheckStatus("1");
				}
				otdDao.update(otd);
				break;
			case 1: // 赎回
				otd = otdDao.getOnlineTransferDetailByLocalSeqNo(localSeqNo);
				if (BigInteger.valueOf(Long.parseLong(amount)) != otd
						.getAmount()) {
					// 记录日志 该条交易明细核对错误

					// 修改对账状态为不一致
					otd.setCheckStatus("2");
					flag = false;
				} else {// 修改对账状态为一致
					otd.setCheckStatus("1");
				}
				otdDao.update(otd);
				break;
			}
		}
		return flag;
	}

	/**
	 * 公共异常抛出方法
	 * 
	 * @param error
	 * @throws PCPSApplicationException
	 */
	private void errException(String error) throws PCPSApplicationException {
		throw new PCPSApplicationException(
				PCPSApplicationException.ERRCODE_CATEGORY_APPLICATION, "",
				error);
	}
}
